﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;

namespace Parallel3M.parallel3m.framework
{
    public class ParallelProcessor : ParallelElement
    {
        public String runtype = PROCESSORCONSTANT.RUNTYPE_THREAD;        
        public bool isFirstProcess = true;

        Thread thread;
        Task task;

        public void start() {

            if (status == PROCESSORCONSTANT.STATUS_COMPLETED)
            {
                return;
            }
            else
            {
                status = PROCESSORCONSTANT.STATUS_RUNNING;
                if (runtype == PROCESSORCONSTANT.RUNTYPE_THREAD)
                {
                    thread = new Thread(new ThreadStart(run));
                    thread.Start();
                }
                else
                {
                    task = new Task(() => run());
                    task.Start();
                }
            }
        }

        public void stop() {
            if (status == PROCESSORCONSTANT.STATUS_COMPLETED)
            {
                return;
            }
            else
            {
                status = PROCESSORCONSTANT.STATUS_STOP;
            }
        }

        public void ChangeRunType()
        {
            if (status == PROCESSORCONSTANT.STATUS_RUNNING)
            {
                status = PROCESSORCONSTANT.STATUS_RUNTYPE_CHANGE;
            }
            else
            {
                if (runtype == PROCESSORCONSTANT.RUNTYPE_THREAD)
                {
                    runtype = PROCESSORCONSTANT.RUNTYPE_TASK;
                }
                else
                {
                    runtype = PROCESSORCONSTANT.RUNTYPE_THREAD;
                }
            }
        }
        

        public void run() {

            while (status == PROCESSORCONSTANT.STATUS_RUNNING)
            {
                process();                
            }

            if (status == PROCESSORCONSTANT.STATUS_RUNTYPE_CHANGE)
            {
                if (runtype == PROCESSORCONSTANT.RUNTYPE_THREAD)
                {
                    runtype = PROCESSORCONSTANT.RUNTYPE_TASK;
                }
                else
                {
                    runtype = PROCESSORCONSTANT.RUNTYPE_THREAD;
                }

                start();
            }
            else if (status == PROCESSORCONSTANT.STATUS_COMPLETED)
            {                            
                destroy();
            }
        }


        public virtual void process()
        {
            //get the payload
            //payload execute
            //output the payload            
            Console.WriteLine("ProcessorID:" + id + " is processing.....");
        }

        public virtual void destroy()
        {

        }


        //parse
        public override void PreParse()
        {
            base.PreParse();
            String run_type = (String)parseParameters["runtype"];
            if (run_type == "TASK")
            {
                runtype = PROCESSORCONSTANT.RUNTYPE_TASK;
            }
            else
            {
                runtype = PROCESSORCONSTANT.RUNTYPE_THREAD;
            }

            //parse the payload graph


        }
             
    }
}
